unit oFormSimulation;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
 Mathematic, Vector, RenderContext, View, Pedestrian, Obstacle, Path, uOSPRand, GL, GLu,
 Menus, Buttons, CheckLst, oProcessObjectConstants, oEntityTypeConstants, oStatisticProcessor,
 oProcessObjects, OProcessItem, oEditorManager, schodyFrm, oStatisticEventConstants,
 oFrameLL, oFrameScene, oSimulation, oArrivalsMAnager,
 Generics.Collections, ActnList, ToolWin, ActnMan, ActnCtrls,
  PlatformDefaultStyleActnCtrls, ImgList, oFrameProgress;

type


  TformSimulation = class(TForm)
    TfEditor1: TfEditor;
    actmanSimulation: TActionManager;
    atbSimuation: TActionToolBar;
    actionStart: TAction;
    actionPause: TAction;
    actionStop: TAction;
    actionShowOutput: TAction;
    actionHideOutput: TAction;
    actionIncEvery: TAction;
    actionDecEvery: TAction;
    actionIncSleepTime: TAction;
    actionDecSleepTime: TAction;
    ImgLstSimulation: TImageList;
    ActionSleepPeriod: TAction;
    ActionSleepTime: TAction;
    frmProgress: TFrameProgress;
    procedure aFramebtnStartClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure actionStartExecute(Sender: TObject);
    procedure actionPauseExecute(Sender: TObject);
    procedure actionStopExecute(Sender: TObject);
    procedure actionShowOutputExecute(Sender: TObject);
    procedure actionHideOutputExecute(Sender: TObject);
    procedure actionIncEveryExecute(Sender: TObject);
    procedure actionDecEveryExecute(Sender: TObject);
    procedure actionIncSleepTimeExecute(Sender: TObject);
    procedure actionDecSleepTimeExecute(Sender: TObject);
    procedure ActionSleepPeriodExecute(Sender: TObject);
    procedure ActionSleepTimeExecute(Sender: TObject);
  private
    { Private declarations }
    aMain: TForm;
    aSimulation: TPedSimulation;
    aStatPath : string;
  public
    { Public declarations }
    property StatisticPath : string read aStatPath write aStatPath;
    property Simulation: TPedSimulation read aSimulation write aSimulation;
    property StatPath : string read aStatPath write aStatPath;
    property Form: TForm read aMain write aMain;
    property GLFrame: TfEditor read TfEditor1;
  end;

var
  formSimulation: TformSimulation;

implementation

uses
  fMain, oRunPropertiesManager, oMasterManager;

resourcestring sleepperiod = 'actual sleep period is set to ';
resourcestring sleeptime = 'actual sleep time is set to ';


{$R *.dfm}

procedure TformSimulation.actionDecEveryExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_DEC_PERIOD, NIL));
end;

procedure TformSimulation.actionDecSleepTimeExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_DEC_TIME, NIL));
end;

procedure TformSimulation.actionHideOutputExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_DISABLE_OUTPUT, NIL));
end;

procedure TformSimulation.actionIncEveryExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_INC_PERIOD, NIL));
end;

procedure TformSimulation.actionIncSleepTimeExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_INC_TIME, NIL));
end;

procedure TformSimulation.actionPauseExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_PAUSE, NIL));
end;

procedure TformSimulation.actionShowOutputExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_ENABLE_OUTPUT, NIL));
end;

procedure TformSimulation.ActionSleepPeriodExecute(Sender: TObject);
begin
  MessageDlg(sleepperiod + FloatToStr(frmMain.Master.SimRenderer.SimGUI.ZaspatKazdych),mtInformation,[mbOK],0);
end;

procedure TformSimulation.ActionSleepTimeExecute(Sender: TObject);
begin
  MessageDlg(sleeptime + FloatToStr(frmMain.Master.SimRenderer.SimGUI.ZaspatNa),mtInformation,[mbOK],0);
end;

procedure TformSimulation.actionStartExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_START, NIL));
end;

procedure TformSimulation.actionStopExecute(Sender: TObject);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_STOP, NIL));
end;

procedure TformSimulation.aFramebtnStartClick(Sender: TObject);
var
  item: TProcessItem;
  prop: String;
  i: Integer;
  arr : TArrivalsManager.TArrivalType;
  properties: TRunPropertiesManager.TRunPropertiesType;
  aStatL : TextFile;
  statProcessor : TStatisticProcessor;
  list : TPRocessingList;
begin
  item := (Form as TfrmMain).Master.ProcessObject(TProcessItem.create(PO_TREE_GET_CHECKED,nil));
  prop := (item.Data as TConfignData).RunConfig;
  item := (Form as TfrmMain).Master.ProcessObject(TProcessItem.create(PO_RUNPROPMAN_GET_RUN_PROPERTIES,TString.Create(prop)));
  properties := item.Data as TRunPropertiesManager.TRunPropertiesType;


  for i := 1 to round(properties.Replications) do
    begin
      {this message can be use by anyone. I made it free to edit for anyone. so if you need to
      initialize the arrivals statistics or something else to do with arrivals, just go to
      arrivals manager, find PO_ARRMAN_ACTIVATE code and insert your code. there are some lines
      out-commented, because i have no idea, what is their purpose}
      (Form as TfrmMain).Master.ProcessObject(TProcessItem.create(PO_ARRMAN_ACTIVATE,nil));
      Simulation := TPedSimulation.Create((Form as TfrmMain).Master.SceneManager.Scene,
                                          (Form as TfrmMain).Master.ArrivalsManager.Arrivals,
                                          properties);
      if not DirectoryExists(StatisticPath + '\replication' + IntToStr(i)) then
        MkDir(StatisticPath + '\replication' + IntToStr(i));

      Simulation.StatisticDir := StatisticPath + '\replication' + IntToStr(i);
      Simulation.prepareStatFiles(properties.Stats, TStatisticProcessor.getStatisticTypes);
      Simulation.Simulation;

      for arr in (Form as TfrmMain).Master.ArrivalsManager.Arrivals do
       begin
         if arr.StatPeople <> nil then
           Simulation.writeStaticticEvent(SE_PEOPLE_IN_ARRIVAL, arr.Name, arr.StatPeople.Value);
       end;

      //write each arrivals stat into file (if any)
      //write simulation stat into file (if any)
      Simulation.writeStaticticEvent(SE_PEOPLE_IN_MODEL, Simulation.StatPeopleInModel.Mean,
                  Simulation.StatPeopleInModel.Dispersion);
      Simulation.closeStatFiles;
      aSimulation.Free;
      aSimulation := nil;
    end;

  list := TProcessingList.Create;
  list.addParameter(TInteger.Create(round(properties.Replications)));
  list.addParameter(TString.Create(StatisticPath));
  list.addParameter(TProcessingBoolList.Create(properties.Stats));
  (Form as TfrmMain).Master.ProcessObject(
        TProcessItem.create(PO_EDITOR_STAT_SET_PARAMS, list));

end;

procedure TformSimulation.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  frmMain.Master.ProcessObject(TProcessItem.create(PO_SIM_RENDERER_CLOSE, NIL));
end;

procedure TformSimulation.FormCreate(Sender: TObject);
var Pedestrian: TPedestrianEditor;
    pos : TVector;
begin
 inherited;
 with TfEditor1 do begin
    Application.OnIdle :=  IdleLoop;
    try
      LevelSize := tMasterManager.getStaticMaster.SceneManager.Scene.getLevelSize(0);
    except
      LevelSize := 1;
    end;
    ViewWidth := LevelSize;
    RenderContext := TRenderContext.Create;
    SimRBtn.Checked:= true;

    PolyBtn.Visible:= false;
    CircleBtn.Visible:= false;
    SpawnBtn.Visible:= false;
    SinkBtn.Visible:= false;
    PathPointBtn.Visible:= false;
    PathWayBtn.Visible:= false;

    if not RenderContext.Init(RenderPanel.Handle, true) then Caption := 'RenderContext.Init Error';
    // OrthogonalView := TOrthogonalView.Create;
    pos := TVector.Create(LevelSize / 2, LevelSize / 2, 0);
    OrthogonalView := TOrthogonalView.Create(pos, ViewWidth, ViewWidth, 0);

    Pedestrians := TPedestriansList.Create;
    Obstacles := TObstaclesList.Create;
    LogObstacles:= TObstaclesList.Create;
    Spawns:= TObstaclesList.Create;
    Sinks:= TObstaclesList.Create;
    PathPoints:= TObstaclesList.Create;
    AllObstacles:= TObstaclesList.Create;
    Path:= TPath2.Create;

    PickedPedestrianIndex := -1;
    PickedObstacleIndex := -1;
    PickedSpawnIndex := -1;
    PickedSinkIndex := -1;
    PickedPathPointIndex := -1;
    PickedPointIndex := -1;
    PickedPointIndex1 := -1;
    PickedPointIndex2 := -1;
    PickedPointIndex3 := -1;
    PolygonObstacle := nil;
    CircleObstacle := nil;
    R := 0.5; G := 0.5; B := 0.5;

    // nastavenie velkosti mriezky
    GridX := 1; GridY := 1;

    Start := false;
    // vytvorenie GL sceny
    InitGLScene;
    Randomize;
//    schodyFrm:= TSchodiskoFrm.Create(self);
    Creating:= false;
  end;

end;

procedure TformSimulation.FormDestroy(Sender: TObject);
var I: Integer;
begin
  with TfEditor1 do begin
    RenderContext.Relase;
    RenderContext.Free;
    OrthogonalView.Free;
    for I := 0 to Pedestrians.Count -1 do begin
        TPedestrianEditor(Pedestrians[I]).Free;
    end;
    Pedestrians.Free;

    for I := 0 to Obstacles.Count -1 do begin
        TObstacle(Obstacles[I]).Free;
    end;
    Obstacles.Free;

    for I := 0 to LogObstacles.Count - 1 do begin
        TObstacle(LogObstacles[I]).Free;
    end;
    LogObstacles.Free;

    for I := 0 to Spawns.Count - 1 do begin
      TObstacle(Spawns[I]).Free;
    end;
    Spawns.Free;

    for I := 0 to Sinks.Count - 1 do begin
      TObstacle(Sinks[I]).Free;
    end;
    Sinks.Free;

    for I := 0 to PathPoints.Count - 1 do begin
      TObstacle(PathPoints[I]).Free;
    end;
    PathPoints.Free;


  end;
end;

end.
